package com.enfi.api.modules.ext.mq.strategy;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.enfi.api.modules.db.entity.Warning;
import com.enfi.api.modules.db.entity.WarningConfig;
import com.enfi.api.modules.db.entity.WarningRole;
import com.enfi.api.modules.db.service.WarningConfigService;
import com.enfi.api.modules.db.service.WarningRoleService;
import com.enfi.api.modules.db.service.WarningService;
import com.enfi.api.modules.ext.jpush.PushBean;
import com.enfi.api.modules.ext.jpush.PushService;
import com.enfi.api.modules.ext.mq.common.MessageTypeEnum;
import com.enfi.api.modules.ext.mq.common.MqConstants;
import com.enfi.api.modules.ext.mq.common.PushTypeEnum;
import com.enfi.api.modules.ext.mq.common.PushWayEnum;
import com.enfi.api.modules.ext.mq.factory.MessageFactory;
import com.enfi.api.modules.ext.websocket.service.WsService;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;

/**
 * 预警策略
 * @author xukk
 * @date 2020/3/10
 */
@Service
@Slf4j
public class WarningStrategy implements BaseStrategy , InitializingBean {
    private WsService wsService;
    @Autowired
    private PushService pushService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private WarningService warningService;
    @Autowired
    private WarningRoleService warningRoleService;
    @Autowired
    private WarningConfigService warningConfigService;
    @Override
    public void handle(JSONObject jsonObject) {
        Integer pushType=jsonObject.getInteger(MqConstants.ST.PUSH_TYPE);
        String pushWay=jsonObject.getString(MqConstants.ST.PUSH_WAY);
        if(pushType==null){
            // 默认走websocket
            pushType= PushTypeEnum.WEBSOCKET.getCode();
            jsonObject.put(MqConstants.ST.PUSH_TYPE,pushType);
        }
        if(StringUtils.isEmpty(pushWay)){
            pushWay= PushWayEnum.PC.name();
            jsonObject.put(MqConstants.ST.PUSH_WAY,pushWay);
        }
        Warning warning=saveOrUpdate(jsonObject);
        push(warning);
        log.warn("此次处理结束");

    }

    @DS("secondary")
    public Warning saveOrUpdate(JSONObject jsonObject){
        JSONObject jo=jsonObject.getJSONObject("data");
        log.warn("jo:{}",jo);
        Warning warning = jo.toJavaObject(Warning.class);
        if(org.apache.commons.lang3.StringUtils.equalsIgnoreCase(warning.getCurrValue(),"Infinity")){
            return null;
        }
        warning.setStatus(0);
        warning.setViewNum(0);
        try{
            //查找采集项信息，根据source类型 1,3查询automatic_system_menu_all 2、4查询process_operation_menu_all
            if(warning.getSource() != null && (warning.getSource() == 1 || warning.getSource() == 3)){
                String sql = "select * from automatic_system_menu_all where sensor_code = '"+warning.getCode()+"'";
                Map<String, Object> map = jdbcTemplate.queryForMap(sql);
                if(map != null){
                    warning.setFactoryCode(map.get("factory_code").toString());
                    warning.setFactory(map.get("factory").toString());
                    warning.setProcessCode(map.get("monitor_code").toString());
                    warning.setProcessName(map.get("monitor_name").toString());
                    warning.setIndexCode(map.get("sensor_code").toString());
                    warning.setIndexName(map.get("sensor_name").toString());
                    warning.setTagStage(map.get("tag_stage").toString());
                }
            }
            if(warning.getSource() != null && (warning.getSource() == 2 || warning.getSource() == 4)){
                String sql = "select * from process_operation_menu_all where code = '"+warning.getCode()+"'";
                Map<String, Object> map = jdbcTemplate.queryForMap(sql);
                if(map != null){
                    warning.setFactoryCode(map.get("factory_code").toString());
                    warning.setFactory(map.get("factory").toString());
                    warning.setProcessCode(map.get("name").toString());
                    warning.setProcessName(map.get("name").toString());
                    warning.setIndexCode(map.get("code").toString());
                    warning.setIndexName(map.get("fz").toString());
                }
            }
        }catch (Exception e){
            log.warn("warningStrategy.save() error:{}",e.getMessage());
        }
        warningService.save(warning);
        return warning;
    }

    @DS("master")
    @Async
    public void push(Warning warning){
        WarningConfig warningConfig = new WarningConfig();
        warningConfig.setSource(warning.getSource());
        warningConfig.setLevel(warning.getLevel());
        warningConfig.setStatus(1);
        warningConfig.setFactoryCode(warning.getFactoryCode());
        List<WarningConfig> warningConfigs = warningConfigService.findAll(Example.of(warningConfig));
        warningConfigs.forEach(v -> {
                    List<WarningRole> warningRoleList = Lists.newArrayList();
                    v.getWarningConfigRoleList().forEach(t -> {
                        WarningRole warningRole = new WarningRole();
                        warningRole.setRoleId(t.getRoleId());
                        warningRole.setWarningId(warning.getId());
                        warningRole.setRoleName(t.getRoleName());
                        warningRoleList.add(warningRole);
                    });
                    List userCodeList=Lists.newArrayList();
                    v.getWarningConfigRoleList().forEach(t->{
                        List<Map<String, Object>> list1 = jdbcTemplate.queryForList("select distinct  t2.user_code,t2.login_code,t2.user_name from js_sys_user_role t1 left join js_sys_user t2 on t1.user_code=t2.user_code where role_code=?", t);
                        if (!CollectionUtils.isEmpty(list1)) {
                            list1.forEach(t1 -> {
                                Map map = (Map) t1;
                                userCodeList.add(map.get("user_code").toString());
                            });
                        }
                    });
                    warningRoleService.saveAll(warningRoleList);
                    log.warn("warningStrategy pushPlatForm");
                    switch (v.getPlatform()){
                        case 1:
                            JSONObject j1 = new JSONObject();
                            JSONObject data=new JSONObject();
                            data.put("title",warning.getTitle());
                            j1.put(MqConstants.ST.MESSAGE_TYPE,MessageTypeEnum.WARNING.name().toLowerCase());
                            j1.put(MqConstants.ST.RESP_TYPE,1);
                            j1.put(MqConstants.ST.PUSH_WAY,PushWayEnum.PC.name().toLowerCase());
                            j1.put(MqConstants.ST.USER_LIST, Joiner.on(",").join(userCodeList));
                            j1.put(MqConstants.ST.DATA,data.toString());
                            try {
                                wsService.handleFromMq(j1);
                            } catch (Exception e) {
                                log.warn(e.getMessage());
                            }
                            break;
                        case 2:
                            try{
                                PushBean pushBean=new PushBean();
                                pushBean.setAlert(warning.getTitle());
                                log.warn("推送app消息:{},userCode:{}",pushBean,userCodeList);
                                pushService.pushAll(pushBean,userCodeList);
                            }catch (Exception e){
                                log.warn(e.getMessage());
                            }
                            break;
                        case 3:
                            break;
                        case 4:
                            break;
                        default:
                    }
                }
        );
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        MessageFactory.register(MessageTypeEnum.WARNING, this);
    }
    @Autowired
    public void setWsService(WsService wsService) {
        this.wsService = wsService;
    }
}
